﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using WebCrawler.HttpConnection.Interfaces;
using System.Windows.Forms;
using GlobalInterfaces;

namespace WebCrawler.HttpConnection
{
    public class HttpRequest : IHttp, IObservable
    {
        private static IList<IObserver> _observers = new List<IObserver>();
        private WebRequest _request;
        private WebResponse _response;
        private string _host;

        public Uri Url { get; set; }
        public string ServerUrl { get; set; }
        public string PathUrl { get; set; }
        public string Content { get; set; }

        public bool NotFound { get; protected set; }
        public bool IsReady { get; set; }
        public bool UrlIsValid { get; set; }

        public HttpRequest(string url, IList<IObserver> os)
            : this(url)
        {
            _observers = os;
        }
        public HttpRequest(string url)
        {
            Uri newUri;
            if (Uri.TryCreate(url, UriKind.Absolute, out newUri))
            {
                Url = newUri;
                UrlIsValid = true;
            }

            CreateRequest();
        }

        public void CreateRequest()
        {
            if (!UrlIsValid)
                return;

            _request = WebRequest.Create(Url);
            _request.Timeout = 5000;
            try
            {
                _response = _request.GetResponse();
                _host = _response.ResponseUri.Host;

                ServerUrl = GetServerUrl();
                PathUrl = GetCurrentPath();
                Content = GetAllContent();
                IsReady = true;
                NotifyAll("1|" + _response.ResponseUri.AbsoluteUri);
            }
            catch (Exception ex)
            {
                Console.WriteLine("1|" + Url.OriginalString);
                IsReady = false;
                NotFound = true;
                NotifyAll("0|" + ex.Message);
            }
        }

        // Content stream
        private string GetAllContent()
        {
            Stream stream = _response.GetResponseStream();
            StreamReader reader = new StreamReader(stream);
            return reader.ReadToEnd();
        }

        //URL to current path 
        private string GetCurrentPath()
        {
            string path = "";
            Match m = Regex.Match(_response.ResponseUri.AbsoluteUri, "/", RegexOptions.RightToLeft);
            if (m == null)
                path = _response.ResponseUri.AbsoluteUri + "/";
            else
                path = _response.ResponseUri.AbsoluteUri.Substring(0, m.Index) + "/";

            return path;
        }

        //URL to server
        private string GetServerUrl()
        {
            string serverUrl = "";
            Match m = Regex.Match(_response.ResponseUri.AbsoluteUri, _host,
                RegexOptions.RightToLeft | RegexOptions.IgnoreCase);
            if (m == null)
                serverUrl = _response.ResponseUri.AbsoluteUri;
            else
                serverUrl = _response.ResponseUri.AbsoluteUri.Substring(0, m.Index + _host.Length);

            return serverUrl;
        }

        public void NotifyAll(object obj)
        {
            foreach (IObserver o in _observers)
            {
                o.Update(obj);
            }
        }
    }
}
